package com.sojson.project.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.sojson.enums.core.EModuleNo;
import com.sojson.project.dao.CouponGoodsDao;
import com.sojson.project.dao.GoodSpecsDao;
import com.sojson.project.dao.GoodsDao;
import com.sojson.project.dao.HotelDao;
import com.sojson.project.dao.HotelRoomDao;
import com.sojson.project.entity.bo.CouponUseGoodsParam;
import com.sojson.project.entity.bo.CouponUseResponse;
import com.sojson.project.entity.bo.OrderGoodsParam;
import com.sojson.project.entity.bo.OrderParam;
import com.sojson.project.entity.bo.OrderStoreParam;
import com.sojson.project.entity.po.CouponGoods;
import com.sojson.project.entity.po.GoodSpecs;
import com.sojson.project.entity.po.Goods;
import com.sojson.project.entity.po.Hotel;
import com.sojson.project.entity.po.HotelRoom;
import com.sojson.project.service.CouponGoodsService;
import com.sojson.project.service.CouponService;
import com.sojson.project.sys.user.dao.UserDao;
import com.sojson.project.sys.user.entity.po.User;
import com.sojson.util.DateUtil;
import com.sojson.util.ExpUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.id.IdUtil;

/**
 * 券可用商品Service实现类
 * 
 * @author liu
 * @date 2021-06-02
 */
@Service
public class CouponGoodsServiceImpl implements CouponGoodsService {

    @Lazy
    @Autowired
    private CouponGoodsServiceImpl couponGoodsService;
    @Autowired
    private CouponService couponService;
    @Resource
    private CouponGoodsDao couponGoodsDaoImpl;
    @Resource
    private HotelRoomDao hotelRoomDaoImpl;
    @Resource
    private HotelDao hotelDaoImpl;
    @Resource
    private UserDao userDaoImpl;
    @Resource
    private GoodsDao goodsDaoImpl;
    @Resource
    private GoodSpecsDao goodSpecsDaoImpl;

    /**
     * 单条插入
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int insert(CouponGoods couponGoods) {
        int insert = couponGoodsDaoImpl.insert(couponGoods);
        return insert;
    }

    /**
     * 批量插入
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int insertList(CouponGoods couponGoods) {
        int insertList = couponGoodsDaoImpl.insertList(couponGoods.getCouponGoodss());
        return insertList;
    }

    /**
     * 通过对象批量删除(物理删除)
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int deleteByDto(CouponGoods couponGoods) {
        int deleteByDto = couponGoodsDaoImpl.deleteByDto(couponGoods);
        return deleteByDto;
    }

    /**
     * 统计全部数量
     * 
     * @return
     */
    @Override
    public int countAll() {
        int countAll = couponGoodsDaoImpl.countAll();
        return countAll;
    }

    /**
     * 查询所有
     * 
     * @return
     */
    @Override
    public List<CouponGoods> listAll() {
        List<CouponGoods> findAll = couponGoodsDaoImpl.listAll();
        return findAll;
    }

    /**
     * 根据对象统计数量
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int countByDto(CouponGoods couponGoods) {
        int countByDto = couponGoodsDaoImpl.countByDto(couponGoods);
        return countByDto;
    }

    /**
     * 根据对象查询
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public List<CouponGoods> listByDto(CouponGoods couponGoods) {
        List<CouponGoods> findByDto = couponGoodsDaoImpl.listByDto(couponGoods);
        return findByDto;
    }

    /**
     * 通过id删除(物理删除)
     * 
     * @param id
     * @return
     */
    @Override
    public int deleteById(Integer id) {
        int deleteById = couponGoodsDaoImpl.deleteById(id);
        return deleteById;
    }

    /**
     * 通过id数组删除(物理删除)
     * 
     * @param ids
     * @return
     */
    @Override
    public int deleteByIds(Integer[] ids) {
        int deleteByIds = couponGoodsDaoImpl.deleteByIds(ids);
        return deleteByIds;
    }

    /**
     * 通过id更新(全部更新)
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int updateAllById(CouponGoods couponGoods) {
        int updateAllById = couponGoodsDaoImpl.updateAllById(couponGoods);
        return updateAllById;
    }

    /**
     * 通过id列表更新(全部更新)(更新内容相同)
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int updateAllByIdList(CouponGoods couponGoods) {
        int updateAllByIdList = couponGoodsDaoImpl.updateAllByIdList(couponGoods);
        return updateAllByIdList;
    }

    /**
     * 通过id列表更新(全部更新)(更新内容不相同)
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int updateDtoListAllById(CouponGoods couponGoods) {
        int updateDtoListAllById = couponGoodsDaoImpl.updateDtoListAllById(couponGoods.getCouponGoodss());
        return updateDtoListAllById;
    }

    /**
     * 通过id更新(局部更新)
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int updateById(CouponGoods couponGoods) {
        int updateById = couponGoodsDaoImpl.updateById(couponGoods);
        return updateById;
    }

    /**
     * 通过id列表更新(局部更新)(更新内容相同)
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int updateByIdList(CouponGoods couponGoods) {
        int updateByIdList = couponGoodsDaoImpl.updateByIdList(couponGoods);
        return updateByIdList;
    }

    /**
     * 通过id列表更新(局部更新)(更新内容不相同)
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public int updateDtoListById(CouponGoods couponGoods) {
        int updateDtoListById = couponGoodsDaoImpl.updateDtoListById(couponGoods.getCouponGoodss());
        return updateDtoListById;
    }

    /**
     * 通过id查询
     * 
     * @param id
     * @return
     */
    @Override
    public CouponGoods findById(Integer id) {
        CouponGoods findById = couponGoodsDaoImpl.findById(id);
        return findById;
    }

    /**
     * 通过id数组查询
     * 
     * @param ids
     * @return
     */
    @Override
    public List<CouponGoods> findByIds(Integer[] ids) {
        List<CouponGoods> findByIds = couponGoodsDaoImpl.findByIds(ids);
        return findByIds;
    }

    /**
     * 通过对象查询id列表
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public List<Integer> findIdByDto(CouponGoods couponGoods) {
        List<Integer> findIdByDto = couponGoodsDaoImpl.findIdByDto(couponGoods);
        return findIdByDto;
    }

    /**
     * 清空数据(物理清空)
     */
    @Override
    public int clear() {
        return couponGoodsDaoImpl.clear();
    }

    /**
     * 根据对象查询
     * 
     * @param couponGoods
     * @return
     */
    @Override
    public List<CouponGoods> list(CouponGoods couponGoods) {
        return couponGoodsDaoImpl.list(couponGoods);
    }

    /**
     * 获取商城优惠金额
     * 
     * @param orderParam
     * @return
     * @throws Exception
     */
    @Override
    public List<CouponUseResponse> getPriceGoods(OrderParam orderParam) throws Exception {
        return couponGoodsService.getPriceGoods(orderParam, orderParam.getOrderStoreParams());
    }

    public List<CouponUseResponse> getPriceGoods(OrderParam orderParam, List<OrderStoreParam> orderStores)
        throws Exception {
        String noShop = IdUtil.uuid();
        List<CouponUseResponse> couponUseResponses = new ArrayList<>();

        for (OrderStoreParam orderStore : orderStores) {
            couponUseResponses.add(couponGoodsService.getPriceGoods(orderParam, orderStore, noShop));
        }
        return couponUseResponses;
    }

    public CouponUseResponse getPriceGoods(OrderParam orderParam, OrderStoreParam orderStoreParam, String noShop)
        throws Exception {
        // 优惠券编号
        String couponNos = orderStoreParam.getCouponNos();

        // 店铺编号
        String storeNo = null;
        // 商品总价
        BigDecimal pri = new BigDecimal("0");
        // 订单参数
        List<OrderGoodsParam> param = orderStoreParam.getOrderGoodsParams();
        // 优惠券使用的商品
        Map<String, CouponUseGoodsParam> cugps = new HashMap<>();

        // 验证商品参数是否正确
        for (OrderGoodsParam orderGoodsParam : param) {
            GoodSpecs gs = goodSpecsDaoImpl.findById(orderGoodsParam.getGoodSpecsId());
            // 商品数量
            Integer goodNum = orderGoodsParam.getGoodNum();
            // 判断商品规格是否存在
            if (StringUtil.isBlankObject(gs)) {
                ExpUtil.throwEx("商品规格不存在！");
            }

            Goods g = goodsDaoImpl.findById(gs.getGoodId());
            if (StringUtil.isBlankObject(g)) {
                ExpUtil.throwEx("商品不存在！");
            }
            String goodsNo = g.getNo();
            CouponUseGoodsParam couponUseGoodsParam = cugps.get(goodsNo);
            if (StringUtil.isBlankObject(couponUseGoodsParam)) {
                CouponUseGoodsParam cugp = new CouponUseGoodsParam();
                cugp.setUseGoodsNo(goodsNo);
                cugp.setTotal(g.getPrice());
                cugps.put(goodsNo, cugp);
            } else {
                couponUseGoodsParam.setTotal(couponUseGoodsParam.getTotal().add(g.getPrice()));
            }

            User user = userDaoImpl.findById(g.getUserNo());
            if (StringUtil.isBlankObject(storeNo)) {
                storeNo = user.getId();
            }

            // 计算价格
            // 商品原价
            // BigDecimal originalPrice = gs.getPrice();
            // 商品单价
            BigDecimal p = gs.getPrice();
            // 此规格商品总价
            BigDecimal multiply = p.multiply(new BigDecimal(String.valueOf(goodNum)));
            // 订单显示价格累计
            // showTotal = showTotal.add(originalPrice.multiply(new BigDecimal(String.valueOf(goodNum))));
            // 订单总价累计
            pri = pri.add(multiply);
        }

        // 使用优惠券
        Collection<CouponUseGoodsParam> values = cugps.values();
        List<CouponUseGoodsParam> CouponUseGoodsParams = new ArrayList<>();
        for (CouponUseGoodsParam couponUseGoodsParam : values) {
            CouponUseGoodsParams.add(couponUseGoodsParam);
        }

        return couponService.orderArith(couponNos, EModuleNo.SHOPPING_MALL.getCode(), storeNo, CouponUseGoodsParams,
            pri);
    }

    /**
     * 获取酒店优惠金额
     * 
     * @param orderParam
     * @return
     * @throws Exception
     */
    @Override
    public List<CouponUseResponse> getPriceHotel(OrderParam orderParam) throws Exception {
        return couponGoodsService.getPriceHotel(orderParam, orderParam.getOrderStoreParams());
    }

    public List<CouponUseResponse> getPriceHotel(OrderParam orderParam, List<OrderStoreParam> orderStores)
        throws Exception {
        String noShop = IdUtil.uuid();
        List<CouponUseResponse> couponUseResponses = new ArrayList<>();

        for (OrderStoreParam orderStore : orderStores) {
            couponUseResponses.add(couponGoodsService.getPriceHotelGo(orderParam, orderStore, noShop));
        }
        return couponUseResponses;
    }

    public CouponUseResponse getPriceHotelGo(OrderParam orderParam, OrderStoreParam orderStoreParam, String noShop)
        throws Exception {
        // 优惠券编号
        String couponNos = orderStoreParam.getCouponNos();

        // 店铺编号
        String storeNo = null;
        // 入住天数
        long date = DateUtil.getDate(orderStoreParam.getStartTime(), orderStoreParam.getEndTime());
        BigDecimal datePri = new BigDecimal(String.valueOf(date));
        // 商品总价
        BigDecimal pri = new BigDecimal("0");
        // 订单参数
        List<OrderGoodsParam> param = orderStoreParam.getOrderGoodsParams();
        // 优惠券使用的商品
        Map<String, CouponUseGoodsParam> cugps = new HashMap<>();

        // 验证商品参数是否正确
        for (OrderGoodsParam orderGoodsParam : param) {
            HotelRoom g = hotelRoomDaoImpl.findByNo(orderGoodsParam.getGoodSpecsNo());
            // 商品数量
            Integer goodNum = orderGoodsParam.getGoodNum();
            // 判断商品规格是否存在
            if (StringUtil.isBlankObject(g)) {
                ExpUtil.throwEx("房间不存在！");
            }

            // Goods g = goodsDaoImpl.findById(gs.getGoodId());
            // if (StringUtil.isBlankObject(g)) {
            // ExpUtil.throwEx("商品不存在！");
            // }
            // if (g.getStatus() == EGeneralStatus.DISABLE.getCode()) {
            // ExpUtil.throwEx("商品已禁用！");
            // }
            String goodsNo = g.getNo();
            CouponUseGoodsParam couponUseGoodsParam = cugps.get(goodsNo);
            if (StringUtil.isBlankObject(couponUseGoodsParam)) {
                CouponUseGoodsParam cugp = new CouponUseGoodsParam();
                cugp.setUseGoodsNo(goodsNo);
                cugp.setTotal(g.getPrice());
                cugps.put(goodsNo, cugp);
            } else {
                couponUseGoodsParam.setTotal(couponUseGoodsParam.getTotal().add(g.getPrice()));
            }

            Hotel findByNo = hotelDaoImpl.findByNo(g.getNoHotel());
            if (StringUtil.isBlankObject(storeNo)) {
                storeNo = findByNo.getNo();
            }

            // 计算价格
            // 商品单价
            BigDecimal p = g.getPrice();
            // 此规格商品总价
            BigDecimal multiply = p.multiply(new BigDecimal(String.valueOf(goodNum))).multiply(datePri);
            // 订单总价累计
            pri = pri.add(multiply);
        }

        // 使用优惠券
        Collection<CouponUseGoodsParam> values = cugps.values();
        List<CouponUseGoodsParam> CouponUseGoodsParams = new ArrayList<>();
        for (CouponUseGoodsParam couponUseGoodsParam : values) {
            CouponUseGoodsParams.add(couponUseGoodsParam);
        }

        return couponService.orderArith(couponNos, EModuleNo.HOTEL.getCode(), storeNo, CouponUseGoodsParams, pri);
    }

}